#!/usr/bin/python
# coding:utf-8

import asyncore
import smtpd
import smtplib


class SMTPChannel(smtpd.SMTPChannel):

    def __init__(self, server, conn, addr):
        smtpd.asynchat.async_chat.__init__(self, conn)
        self.__server = server
        self.__conn = conn
        self.__addr = addr
        self.__line = []
        self.__state = self.COMMAND
        self.__greeting = 0
        self.__mailfrom = None
        self.__rcpttos = []
        self.__data = ''
        # self.__fqdn = smtpd.socket.getfqdn()
        self.__fqdn = "josephrobinettebiden.top"
        try:
            self.__peer = conn.getpeername()
        except smtpd.socket.error, err:
            # a race condition  may occur if the other end is closing
            # before we can get the peername
            self.close()
            if err[0] != smtpd.errno.ENOTCONN:
                raise
            return
        print >> smtpd.DEBUGSTREAM, 'Peer:', repr(self.__peer)
        self.push('220 %s %s' % (self.__fqdn, smtpd.__version__))
        self.set_terminator('\r\n')

    # SMTP and ESMTP commands
    def smtp_EHLO(self, arg):
        if not arg:
            self.push('501 Syntax: HELO hostname')
            return
        if self.__greeting:
            self.push('503 Duplicate HELO/EHLO')
        else:
            self.__greeting = arg
            self.push('250 %s' % self.__fqdn)

    def smtp_MAIL(self, arg):
        print >> smtpd.DEBUGSTREAM, '===> MAIL', arg
        address = self.__getaddr('FROM:', arg) if arg else None
        if not address:
            self.push('501 Syntax: MAIL FROM:<address>')
            return
        else:
            if "@josephrobinettebiden.top" not in address:
                self.push('504 Syntax: MAIL FROM:<%s>'%address)
                self.push('221 Bye')
                self.close_when_done()
                return
        if self.__mailfrom:
            self.push('503 Error: nested MAIL command')
            return
        self.__mailfrom = address
        print >> smtpd.DEBUGSTREAM, 'sender:', self.__mailfrom
        self.push('250 Ok')


class SMTPServer(smtpd.SMTPServer):

    def handle_accept(self):
        pair = self.accept()
        if pair is not None:
            conn, addr = pair
            print >> smtpd.DEBUGSTREAM, 'Incoming connection from %s' % repr(addr)
            channel = SMTPChannel(self, conn, addr)

    def process_message(self, peer, mailfrom, rcpttos, data):

        for to in rcpttos:
            if "@josephrobinettebiden.top" in to:
                rcpttos.remove(to)
        if not rcpttos:
            return


        # print mailfrom, rcpttos
        server = smtplib.SMTP("127.0.0.1", 25)
        # server.set_debuglevel(1)
        server.sendmail(mailfrom, rcpttos, data)
        server.close()


SMTPServer(('0.0.0.0', 465), None)
asyncore.loop()
